﻿@using SimpleIdServer.IdServer.Authenticate.Handlers;
@using SimpleIdServer.IdServer.Website.Resources;
@using SimpleIdServer.IdServer.Website.Stores.ClientStore;
@using SimpleIdServer.IdServer.Website.Stores.UserStore;
@inherits Fluxor.Blazor.Web.Components.FluxorLayout
@inject NotificationService notificationService
@inject NavigationManager navigationManager
@inject ContextMenuService contextMenuService
@inject DialogService dialogService
@layout MainLayout
@inject IState<UpdateClientState> updateClientState
@inject IDispatcher dispatcher

<RadzenTemplateForm Submit=@UpdateCredential TItem="UpdateClientCredential" Data=@updateClientCredential>
    <!-- Authentication method -->
    <div>
        <RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">@Global.AuthenticationMethod</RadzenText>
        <RadzenDropDown Name="AuthMethod" Class="w-100"
                        Data=@clientCredentialInfos
                        TValue="string"
                        @bind-Value=@updateClientCredential.AuthMethod
                        TextProperty="Name" ValueProperty="AuthMethod" />
        <RadzenRequiredValidator Component="AuthMethod" Text="@Global.AuthenticationMethodRequired"></RadzenRequiredValidator>
    </div>
    @if (updateClientCredential != null && !string.IsNullOrWhiteSpace(updateClientCredential.AuthMethod))
    {        
        <div class="text-muted mt-1">
            <RadzenIcon Icon="info" />
            @(clientCredentialInfos.Single(c => c.AuthMethod == updateClientCredential.AuthMethod).Description)
        </div>
    }

    @switch (updateClientCredential.AuthMethod)
    {
        case OAuthClientSecretPostAuthenticationHandler.AUTH_METHOD:
        case OAuthClientSecretBasicAuthenticationHandler.AUTH_METHOD:
            <!-- Secret-->
            <div>
                <RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">@Global.ClientSecret</RadzenText>
                <RadzenPassword Name="ClientSecret" @bind-Value="@updateClientCredential.ClientSecret" Class="w-100"></RadzenPassword>
                <RadzenRequiredValidator Component="ClientSecret" Text="@Global.ClientSecretRequired"></RadzenRequiredValidator>
            </div>
            break;
        case OAuthClientTlsClientAuthenticationHandler.AUTH_METHOD:
            <!-- TlsClientAuthSubjectDN -->
            <div>
                <RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">@Global.SubjetDistinguishedName</RadzenText>
                <RadzenTextBox Name="TlsClientAuthSubjectDN" @bind-Value="@updateClientCredential.TlsClientAuthSubjectDN" Class="w-100"></RadzenTextBox>
            </div>
            <!-- TlsClientAuthSanDNS -->
            <div>
                <RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">@Global.Dns</RadzenText>
                <RadzenTextBox Name="TlsClientAuthSanDNS" @bind-Value="@updateClientCredential.TlsClientAuthSanDNS" Class="w-100"></RadzenTextBox>
            </div>
            <!-- TlsClientAuthSanEmail -->
            <div>
                <RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">@Global.Email</RadzenText>
                <RadzenTextBox Name="TlsClientAuthSanEmail" @bind-Value="@updateClientCredential.TlsClientAuthSanEmail" Class="w-100"></RadzenTextBox>
            </div>
            <!-- TlsClientAuthSanIP -->
            <div>
                <RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">@Global.Ip</RadzenText>
                <RadzenTextBox Name="TlsClientAuthSanIP" @bind-Value="@updateClientCredential.TlsClientAuthSanIP" Class="w-100"></RadzenTextBox>
            </div>
            break;
    }

    <SidAuthorizeView Roles=@("/clients/manage")>
        <Authorized>
            <RadzenButton class="mt-1" Variant="Variant.Flat" ButtonType="ButtonType.Submit" ButtonStyle="ButtonStyle.Success" Text="@(updateClientState.Value.IsUpdating ? Global.Updating : Global.Save)" Disabled="@(updateClientState.Value.IsUpdating)" />
        </Authorized>
    </SidAuthorizeView>
</RadzenTemplateForm>

@code {
    record UpdateClientCredential
    {
        public string AuthMethod { get; set; } = null!;
        public string? ClientSecret { get; set; } = null;
        public string? TlsClientAuthSubjectDN { get; set; } = null;
        public string? TlsClientAuthSanDNS { get; set; } = null;
        public string? TlsClientAuthSanEmail { get; set; } = null;
        public string? TlsClientAuthSanIP { get; set; } = null;
    }

    record ClientCredentialInfo
    {
        public string Name { get; set; } = null!;
        public string AuthMethod { get; set; } = null!;
        public string Description { get; set; } = null!;
    }

    UpdateClientCredential updateClientCredential = new UpdateClientCredential();
    List<ClientCredentialInfo> clientCredentialInfos = new List<ClientCredentialInfo>
    {
        new ClientCredentialInfo { AuthMethod = OAuthClientSecretPostAuthenticationHandler.AUTH_METHOD, Name = Global.ClientSecretPostName, Description = Global.ClientSecretPostDescription },
        new ClientCredentialInfo { AuthMethod = OAuthClientSecretBasicAuthenticationHandler.AUTH_METHOD, Name = Global.ClientSecretBasicName, Description = Global.ClientSecretBasicDescription },
        new ClientCredentialInfo { AuthMethod = OAuthClientPrivateKeyJwtAuthenticationHandler.AUTH_METHOD, Name = Global.SignedJwtName, Description = Global.SignedJwtDescription },
        new ClientCredentialInfo { AuthMethod = OAuthClientSecretJwtAuthenticationHandler.AUTH_METHOD, Name = Global.SignedJwtClientSecretName, Description = Global.SignedJwtClientSecretDescription },
        new ClientCredentialInfo { AuthMethod = OAuthClientSelfSignedTlsClientAuthenticationHandler.AUTH_METHOD, Name = Global.SelfSignedX509CertificateName, Description = Global.SelfSignedX509CertificateDescription },
        new ClientCredentialInfo { AuthMethod = OAuthClientTlsClientAuthenticationHandler.AUTH_METHOD, Name = Global.X509CertificateName, Description = Global.X509CertificateDescription },
        new ClientCredentialInfo { AuthMethod = OAuthPKCEAuthenticationHandler.AUTH_METHOD, Name = Global.PKCEName, Description = Global.PKCEDescription }
    };

    [Parameter]
    public SimpleIdServer.IdServer.Domains.Client Client { get; set; }

    protected override void OnAfterRender(bool firstRender)
    {
        base.OnAfterRender(firstRender);
        if (firstRender)
        {
            SubscribeToAction<UpdateClientCredentialsSuccessAction>((act) =>
            {
                notificationService.Notify(new NotificationMessage { Severity = NotificationSeverity.Success, Summary = Global.ClientCredentialsUpdated });
                StateHasChanged();
            });
        }
    }

    protected override void OnParametersSet()
    {
        base.OnParametersSet();
        if (Client == null) return;
        updateClientCredential.AuthMethod = Client.TokenEndPointAuthMethod;
        updateClientCredential.ClientSecret = Client.ClientSecret;
        updateClientCredential.TlsClientAuthSubjectDN = Client.TlsClientAuthSubjectDN;
        updateClientCredential.TlsClientAuthSanDNS = Client.TlsClientAuthSanDNS;
        updateClientCredential.TlsClientAuthSanEmail = Client.TlsClientAuthSanEmail;
        updateClientCredential.TlsClientAuthSanIP = Client.TlsClientAuthSanIP;
    }

    void UpdateCredential(UpdateClientCredential updateClientCred)
    {
        var act = new UpdateClientCredentialsAction 
        { 
            AuthMethod = updateClientCred.AuthMethod, 
            ClientId = Client.ClientId,
            ClientSecret = updateClientCred.ClientSecret,
            TlsClientAuthSubjectDN = updateClientCred.TlsClientAuthSubjectDN,
            TlsClientAuthSanDNS = updateClientCred.TlsClientAuthSanDNS,
            TlsClientAuthSanEmail = updateClientCred.TlsClientAuthSanEmail,
            TlsClientAuthSanIP = updateClientCred.TlsClientAuthSanIP
        };
        dispatcher.Dispatch(act);
    }
}